using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Xml;
using OpenQuarters.WebQuarters.Utils;
using OpenQuarters.WebQuarters.Core;

namespace OpenQuarters.WebQuarters.Core.Web.Areas.CMS.Controllers
{
    public class SitemapController : Controller
    {
        public ActionResult Index()
        {
            return SiteMap();
        }

        public ActionResult SiteMap()
        {
            Response.ContentType = "text/xml";

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.UTF8;

            using (XmlWriter writer = XmlWriter.Create(Response.OutputStream, settings))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");

                RenderSitemapNode(CMSPage.HomePage, writer, 0);

                writer.WriteEndElement();
                writer.WriteEndDocument();
            }

            Response.End();

            return View();
        }

        private void RenderSitemapNode(CMSPage page, XmlWriter writer, int level)
        {
            string priority = String.Format("0.{0}", (level > 5) ? 5 : level);
            string url = string.Format("http://{0}{1}", Request.Url.Authority, page.GetUrl());

            if (page.LiveVersion != null && !page.CurrentVersion.NoFollow)
            {
                writer.WriteStartElement("url");
                writer.WriteElementString("loc", url);
                writer.WriteElementString("lastmod", page.CurrentVersion.DateCreated.ToString("yyyy-MM-dd"));
                writer.WriteElementString("priority", priority);

                if (!string.IsNullOrEmpty(page.Reference) && page.Reference.ToUpper() == "HOME")
                    writer.WriteElementString("changefreq", "daily");
                else
                    writer.WriteElementString("changefreq", "weekly");

                writer.WriteEndElement();

                if (page.ChildPages != null && page.ChildPages.Count > 0)
                {
                    foreach (CMSPage childPage in page.ChildPages)
                    {
                        if (childPage.CurrentVersion != null && !childPage.CurrentVersion.NoFollow)
                        {
                            RenderSitemapNode(childPage, writer, level + 1);
                        }
                    }
                }

                foreach (ContentAreaDefinition area in page.LiveVersion.ContentDefinition.Areas)
                {
                    foreach (ModuleDefinition module in area.Modules)
                    {
                        if (GeneralUtils.GetTypeByName(module.ModuleType) != null && GeneralUtils.GetTypeByName(module.ModuleType.ToString()).GetInterfaces().FirstOrDefault(i => i.Name == "IItemListModule`1") != null)
                        {
                            priority = String.Format("0.{0}", (level + 1 > 5) ? 5 : level + 1);

                            object moduleObj = null;
                            Type moduleType = GeneralUtils.GetTypeByName(module.ModuleType);
                            if (moduleType != null)
                            {
                                try
                                {
                                    moduleObj = Activator.CreateInstance(moduleType);
                                    typeof(GeneralUtils).GetMethod("FromJSON", new Type[] { typeof(string), typeof(object) }).MakeGenericMethod(moduleType).Invoke(null, new object[] { module.ModuleJSON, moduleObj });

                                    IList myList = (IList)moduleObj.GetType().GetMethod("ChildItems").Invoke(moduleObj, new object[] { });

                                    foreach (IItemListable item in myList)
                                    {
                                        writer.WriteStartElement("url");
                                        writer.WriteElementString("loc", url + "/" + item.ItemUrl());
                                        writer.WriteElementString("lastmod", page.CurrentVersion.DateCreated.ToString("yyyy-MM-dd"));
                                        writer.WriteElementString("priority", priority);
                                        writer.WriteElementString("changefreq", "daily");
                                        writer.WriteEndElement();
                                    }
                                }
                                catch (NotImplementedException)
                                {
                                }
                            }
                        }
                    }
                }
            }            
        }
    }
}
